package Busquedas;

import Estados.Estado;
import java.util.ArrayList;
import Juegos.Juego;

public class CosteUniforme extends Busqueda{
    private int contadorNodos;
    private int maxContadorNodos;
    ArrayList<Estado> pilaAbiertos;
    ArrayList<Estado> expandidos;
    private long tiempoTotal;
    private boolean controlCiclos;


	public CosteUniforme(Estado ini,Juego juego) {
		super(ini,juego);
                this.expandidos=new ArrayList<Estado>();
                this.pilaAbiertos=new ArrayList<Estado>();
                pilaAbiertos.add(ini);
                tiempoTotal = 0;
	}

	public ArrayList<Estado> resolver(){
        long tiempo1=System.currentTimeMillis();
	boolean solucion = false;
        while (!solucion && this.pilaAbiertos.size()!=0){
            int menor = indiceMenorCoste();
            Estado e=this.pilaAbiertos.remove(menor);
            if(juego.esFinal(e)){
                solucionar(e);
                solucion=true;
            }else{
                generaHijos(e);
            }
            long tiempo2=System.currentTimeMillis();
            tiempoTotal = tiempoTotal + (tiempo2 - tiempo1);
        }
        return this.solucion;
	}

	public int indiceMenorCoste(){
		int menor = pilaAbiertos.get(0).getCoste();
		int indice = 0;
		for (int i = 0; i < pilaAbiertos.size(); i++){
			if (menor > pilaAbiertos.get(i).getCoste()){
				menor = pilaAbiertos.get(i).getCoste();
				indice = i;
			}
		}
		return indice;
	}

        private boolean estaExpandido(Estado e){
        for(int i=0;i<this.expandidos.size();i++){
            if(e.Iguales(e, this.expandidos.get(i)))
                return true;
        }
        return false;


    }

        private void generaHijos(Estado e){
        this.expandidos.add(e);
        int ops=this.juego.getNumOperadores();

        for(int i=0;i<ops;i++){
            Estado nuevo=this.juego.operar(i,e);
            //control de ciclos y de estado peligro
            if( nuevo!=null && !estaExpandido(nuevo) && !juego.esPeligro(nuevo))
                this.pilaAbiertos.add(0, nuevo);
        }
    }

}
